package com.fudan.biz.visualize.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fudan.biz.data.entity.BigDataSource;
import com.fudan.biz.data.service.BigDataSourceService;
import com.fudan.es.EsClient;
import com.fudan.es.aggs.RequestParser;
import com.fudan.es.aggs.ResponseParser;
import com.fudan.es.aggs.entity.ChartRequestEntity;
import com.fudan.es.aggs.entity.ChartResponseEntity;
import com.fudan.es.entity.DimensionPack;
import com.fudan.es.search.QueryService;
import com.fudan.framework.utils.MapUtils;

@Service
public class AggregationService {

	@Autowired
	private RequestParser requestParser;
	@Autowired
	private ResponseParser responseParser;
	@Autowired
	private BigDataSourceService dataSourceService;
	@Autowired
	private QueryService queryService;
	@Autowired
	private EsClient esClient;

	public ChartResponseEntity aggsResponse(String json) throws Exception{

		ChartRequestEntity request = requestParser.buildRequestEntity(json);//将json参数构建成java对象
		DimensionPack dimensionPack = requestParser.buildPack(request);//从request中提取出多维查询的配置，这里DimensionPack是最外层，包括一个维度和多个指标
		//
		AggregationBuilder aggregationBuilder = requestParser.getAggregation(dimensionPack);//得到生成的ES的聚合查询
		String dsId = request.getDsId();//es对应数据集的id
		QueryBuilder queryBuilder = queryService.buildQuery(dsId,request.getQuery());//条件查询
		BigDataSource dataSource = dataSourceService.get(dsId);
		Integer dwId = dataSource.getDwId();
		RestHighLevelClient client = esClient.getClientByDataWareId(dwId);//通过数据集配置得到连接
		SearchSourceBuilder searchSource = new SearchSourceBuilder().size(0);
		searchSource.query(queryBuilder).aggregation(aggregationBuilder);//设置查询条件
		ChartResponseEntity chartResponseEntity = new ChartResponseEntity();//封装返回值
		chartResponseEntity.setRequestJson(json);
		chartResponseEntity.setRealRequest(searchSource.toString());
		SearchResponse response = client.search(new SearchRequest(dataSource.getPath()).source(searchSource),RequestOptions.DEFAULT);
		chartResponseEntity.setRealResponse(response.toString());
		Map<String, Object> map = responseParser.extractResponse(dimensionPack, response);//利用查询配置抽取查询结果集合
		chartResponseEntity.setResponseData(map);
		//extract response
		return chartResponseEntity;
	}


	public void flatData(List<Map<String,Object>> flatMap,Map<String,Object> need,Map<String,Object> data) {
		Set<String> keySet = data.keySet();
		for (String key : keySet) {
			Object subObj = data.get(key);
			if(!Map.class.isAssignableFrom(subObj.getClass())) {
				continue;
			}
			Map<String,Object> sub = (Map<String, Object>) data.get(key);
			Set<String> subKeySet = sub.keySet();
			for (String subKey : subKeySet) {
				Map<String,Object> item = new HashMap<>();
				item.put(key, subKey);
				if(need != null) {
					item.putAll(need);
				}
				Map<String,Object> subMap = (Map<String, Object>) sub.get(subKey);
				Set<String> next = subMap.keySet();
				boolean end = true;
				for (String nk : next) {
					if(nk.matches("[0-9]+")) {
						end = false;
						break;
					}
				}
				if(end) {
					item.putAll(subMap);
					flatMap.add(item);
				}else {
					flatData(flatMap,item,subMap);
				}
			}
		}
	}
}
